<html>
<head><meta charset="utf-8"><title>When is Copy applied to captured values? · general · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/index.html">general</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/When.20is.20Copy.20applied.20to.20captured.20values.3F.html">When is Copy applied to captured values?</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="227606234"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/When%20is%20Copy%20applied%20to%20captured%20values%3F/near/227606234" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jake Goulding <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/When.20is.20Copy.20applied.20to.20captured.20values.3F.html#227606234">(Feb 24 2021 at 14:30)</a>:</h4>
<p>In this code, <code>u32</code> is <code>Copy</code>, so I was surprised to see that <code>move</code> is required to make it work. How does the compiler capture <code>power</code> — by reference or by value? By value is what I would have expected, since <code>pow</code> takes by value, but since <code>move</code> is required it seems like it must be by reference.</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">fn</span> <span class="nf">foo</span><span class="p">(</span><span class="n">power</span>: <span class="kt">u32</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nc">impl</span><span class="w"> </span><span class="nb">Fn</span><span class="p">(</span><span class="kt">i32</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="kt">i32</span> <span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="o">|</span><span class="n">x</span><span class="o">|</span><span class="w"> </span><span class="n">x</span><span class="p">.</span><span class="n">pow</span><span class="p">(</span><span class="n">power</span><span class="p">)</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>
<div class="codehilite"><pre><span></span><code>error[E0373]: closure may outlive the current function, but it borrows `power`, which is owned by the current function
 --&gt; src/lib.rs:3:5
  |
3 |     |x| x.pow(power)
  |     ^^^       ----- `power` is borrowed here
  |     |
  |     may outlive borrowed value `power`
</code></pre></div>



<a name="227606452"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/When%20is%20Copy%20applied%20to%20captured%20values%3F/near/227606452" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Steven Fackler <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/When.20is.20Copy.20applied.20to.20captured.20values.3F.html#227606452">(Feb 24 2021 at 14:31)</a>:</h4>
<p>A non-move closure takes captures by the "least restrictive" mode possible IIRC. Since power is Copy, it can just take a reference and copy that in the closure code, so it does that.</p>



<a name="227606595"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/When%20is%20Copy%20applied%20to%20captured%20values%3F/near/227606595" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jake Goulding <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/When.20is.20Copy.20applied.20to.20captured.20values.3F.html#227606595">(Feb 24 2021 at 14:32)</a>:</h4>
<p>So the compiler would apply the <code>Copy</code> "function call" at closure execution time, not at closure execution time.</p>



<a name="227606675"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/When%20is%20Copy%20applied%20to%20captured%20values%3F/near/227606675" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jake Goulding <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/When.20is.20Copy.20applied.20to.20captured.20values.3F.html#227606675">(Feb 24 2021 at 14:32)</a>:</h4>
<p>And the <code>Copy</code> "function call" would be <code>fn copy(&amp;self) -&gt; Self</code>.</p>



<a name="227606735"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/When%20is%20Copy%20applied%20to%20captured%20values%3F/near/227606735" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Steven Fackler <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/When.20is.20Copy.20applied.20to.20captured.20values.3F.html#227606735">(Feb 24 2021 at 14:32)</a>:</h4>
<p>yeah, it's applied at execution time not construction time</p>



<a name="227606874"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/When%20is%20Copy%20applied%20to%20captured%20values%3F/near/227606874" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Steven Fackler <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/When.20is.20Copy.20applied.20to.20captured.20values.3F.html#227606874">(Feb 24 2021 at 14:33)</a>:</h4>
<p>I think this was basically the reason that move closures were created - we initially thought that the compiler could just figure out the right capture mode, but this is a case where there are multiple "correct" answers unless you start relying on outside constraints on how the closure is used</p>



<a name="227607119"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/When%20is%20Copy%20applied%20to%20captured%20values%3F/near/227607119" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jake Goulding <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/When.20is.20Copy.20applied.20to.20captured.20values.3F.html#227607119">(Feb 24 2021 at 14:35)</a>:</h4>
<p>It's interesting to me because a related thing I've often mused about is which is the "real" copy in code like</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="kd">let</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">42</span><span class="p">;</span><span class="w"></span>
<span class="kd">let</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">a</span><span class="p">;</span><span class="w"> </span><span class="c1">// Is the copy here</span>
<span class="kd">let</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">a</span><span class="p">;</span><span class="w"> </span><span class="c1">// Or here</span>
</code></pre></div>
<p>In generally hasn't mattered because the <em>point</em> of the copy is that both are identical.</p>



<a name="227607452"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/When%20is%20Copy%20applied%20to%20captured%20values%3F/near/227607452" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jake Goulding <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/When.20is.20Copy.20applied.20to.20captured.20values.3F.html#227607452">(Feb 24 2021 at 14:37)</a>:</h4>
<p>Alright, thank you. We ultimately deduced that it <em>had</em> to be copied by reference based on the behavior, but it's hard to see  from inspection of the code because of how <code>Copy</code> is automatically performed by the compiler.</p>



<a name="227614825"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/When%20is%20Copy%20applied%20to%20captured%20values%3F/near/227614825" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Daniel Henry-Mantilla <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/When.20is.20Copy.20applied.20to.20captured.20values.3F.html#227614825">(Feb 24 2021 at 15:23)</a>:</h4>
<p>You can check "where the <code>Copy</code> happens" by looking at the MIR:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">fn</span> <span class="nf">main</span><span class="w"> </span><span class="p">()</span><span class="w"></span>
<span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">power</span><span class="w"> </span><span class="o">=</span><span class="w"> </span>::<span class="n">std</span>::<span class="n">env</span>::<span class="n">args</span><span class="p">().</span><span class="n">len</span><span class="p">()</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="kt">u32</span><span class="p">;</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">_f</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">|</span><span class="n">x</span>: <span class="kt">u32</span><span class="o">|</span><span class="w"> </span><span class="n">x</span><span class="p">.</span><span class="n">pow</span><span class="p">(</span><span class="n">power</span><span class="p">);</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>
<p>yields:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="c1">// WARNING: This output format is intended for human consumers only</span>
<span class="c1">// and is subject to change without notice. Knock yourself out.</span>
<span class="k">fn</span> <span class="nf">main</span>::<span class="p">{</span><span class="n">closure</span><span class="err">#</span><span class="mi">0</span><span class="p">}(</span><span class="n">_1</span>: <span class="kp">&amp;</span><span class="p">[</span><span class="n">closure</span><span class="o">@</span><span class="n">src</span><span class="o">/</span><span class="n">main</span><span class="p">.</span><span class="n">rs</span>:<span class="mi">4</span>:<span class="mi">14</span>: <span class="mi">4</span>:<span class="mi">35</span><span class="p">],</span><span class="w"> </span><span class="n">_2</span>: <span class="kt">u32</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="kt">u32</span> <span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="n">debug</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="n">_2</span><span class="p">;</span><span class="w">                       </span><span class="c1">// in scope 0 at src/main.rs:4:15: 4:16</span>
<span class="w">    </span><span class="n">debug</span><span class="w"> </span><span class="n">power</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">(</span><span class="o">*</span><span class="p">((</span><span class="o">*</span><span class="n">_1</span><span class="p">).</span><span class="mi">0</span>: <span class="kp">&amp;</span><span class="kt">u32</span><span class="p">));</span><span class="w">   </span><span class="c1">// in scope 0 at src/main.rs:3:9: 3:14</span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">_0</span>: <span class="kt">u32</span><span class="p">;</span><span class="w">                     </span><span class="c1">// return place in scope 0 at src/main.rs:4:23: 4:23</span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">_3</span>: <span class="kt">u32</span><span class="p">;</span><span class="w">                     </span><span class="c1">// in scope 0 at src/main.rs:4:23: 4:24</span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">_4</span>: <span class="kt">u32</span><span class="p">;</span><span class="w">                     </span><span class="c1">// in scope 0 at src/main.rs:4:29: 4:34</span>

<span class="w">    </span><span class="n">bb0</span>: <span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="n">StorageLive</span><span class="p">(</span><span class="n">_3</span><span class="p">);</span><span class="w">                 </span><span class="c1">// scope 0 at src/main.rs:4:23: 4:24</span>
<span class="w">        </span><span class="n">_3</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">_2</span><span class="p">;</span><span class="w">                         </span><span class="c1">// scope 0 at src/main.rs:4:23: 4:24</span>
<span class="w">        </span><span class="n">StorageLive</span><span class="p">(</span><span class="n">_4</span><span class="p">);</span><span class="w">                 </span><span class="c1">// scope 0 at src/main.rs:4:29: 4:34</span>
<span class="w">        </span><span class="n">_4</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="o">*</span><span class="p">((</span><span class="o">*</span><span class="n">_1</span><span class="p">).</span><span class="mi">0</span>: <span class="kp">&amp;</span><span class="kt">u32</span><span class="p">));</span><span class="w">         </span><span class="c1">// scope 0 at src/main.rs:4:29: 4:34</span>
<span class="w">        </span><span class="n">_0</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">core</span>::<span class="n">num</span>::<span class="o">&lt;</span><span class="k">impl</span><span class="w"> </span><span class="kt">u32</span><span class="o">&gt;</span>::<span class="n">pow</span><span class="p">(</span><span class="k">move</span><span class="w"> </span><span class="n">_3</span><span class="p">,</span><span class="w"> </span><span class="k">move</span><span class="w"> </span><span class="n">_4</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nc">bb1</span><span class="p">;</span><span class="w"> </span><span class="c1">// scope 0 at src/main.rs:4:23: 4:35</span>
<span class="w">                                         </span><span class="c1">// mir::Constant</span>
<span class="w">                                         </span><span class="c1">// + span: src/main.rs:4:25: 4:28</span>
<span class="w">                                         </span><span class="c1">// + literal: Const { ty: fn(u32, u32) -&gt; u32 {core::num::&lt;impl u32&gt;::pow}, val: Value(Scalar(&lt;ZST&gt;)) }</span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>

<span class="w">    </span><span class="n">bb1</span>: <span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="n">StorageDead</span><span class="p">(</span><span class="n">_4</span><span class="p">);</span><span class="w">                 </span><span class="c1">// scope 0 at src/main.rs:4:34: 4:35</span>
<span class="w">        </span><span class="n">StorageDead</span><span class="p">(</span><span class="n">_3</span><span class="p">);</span><span class="w">                 </span><span class="c1">// scope 0 at src/main.rs:4:34: 4:35</span>
<span class="w">        </span><span class="k">return</span><span class="p">;</span><span class="w">                          </span><span class="c1">// scope 0 at src/main.rs:4:35: 4:35</span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>
<p>Notice the dereference on the <code>_4 = …</code> assignment</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>